//
//  Eyepiece.swift
//  WatermarkCamera
//
//  Created by AxcLogo on 4/7/2024.
//

import UIKit
import Foundation

// MARK: - [YPEyepiece]

extension Eyepiece {
    /// 画幅比枚举
    enum AspectRatio: Int, CaseIterable {
        // 4:3

        case ar_4_3 = 0

        // 16:9

        case ar_16_9 = 1

        // 1:1

        case ar_1_1 = 2

        // 高宽比

        var ratioHW: CGFloat {
            switch self {
            case .ar_1_1: return 1.00000

            case .ar_4_3: return 1.33333

            case .ar_16_9: return 1.77777
            }
        }

        // 裁剪宽高比

        var cropRatioWH: CGFloat {
            switch self {
            case .ar_1_1: return 0.56250

            case .ar_4_3: return 0.75

            case .ar_16_9: return 1
            }
        }
    }

    /// 采集节点
    enum CollectNode {
        // 原生相机节点

        case originalCamera

        // 第一个滤镜节点

        case firstFilter

        // 任意滤镜节点

        case nodeFilter(index: Int)

        // 最后滤镜节点

        case lastFilter

        // 第一个水印节点

        case firstWatermark

        // 任意水印节点

        case nodeWatermark(index: Int)

        // 最后水印节点

        case lastWatermark

        // 最后输出节点

        case lastOutputNode
    }

    /// 镜片链
    class GlassesChain {
        // 头

        var header: GPUImageFilter = .init()

        // 尾

        var footer: GPUImageFilter = .init()
    }
}

// MARK: - [Eyepiece]

class Eyepiece: NSObject {
    // Lifecycle

    override init() {
        super.init()

        config()
    }

    /// Open
    /// 滤镜链
    var filterChain: GlassesChain = .init()

    /// 水印链
    var watermarkChain: GlassesChain = .init()

    /// 设置画幅比
    func setAspectRatio(_ aspectRatio: AspectRatio) {
        guard _aspectRatio != aspectRatio else { return }

        _aspectRatio = aspectRatio

        let ratio = aspectRatio.cropRatioWH

        cropFilter.cropRegion = CGRect(x: 0, y: (1 - ratio) / 2, width: 1, height: ratio)
    }

    /// 获取画幅比
    func aspectRatio() -> AspectRatio {
        return _aspectRatio
    }

    /// 设置画面曝光
    func setExposure(_ bias: CGFloat) {
        exposureFilter.exposure = bias
    }

    /// 获取采集节点
    func outputNode(_ node: CollectNode) -> GPUFilter? {
        var output: GPUFilter?

        switch node {
        case .originalCamera:

            output = inputFilterGroup

        case .firstFilter:

            output = filterList.first?.gpuFilter

        case let .nodeFilter(index):

            output = filterList.axc.object(at: index)?.gpuFilter

        case .lastFilter:

            output = filterList.last?.gpuFilter

        case .firstWatermark:

            output = watermarkList.first?.blendFilter

        case let .nodeWatermark(index):

            output = watermarkList.axc.object(at: index)?.blendFilter

        case .lastWatermark:

            output = watermarkList.last?.blendFilter

        case .lastOutputNode:

            // 倒叙查找

            if let wmLast = watermarkList.last?.blendFilter { // 最后水印
                output = wmLast

            } else if let filterLast = filterList.last?.gpuFilter { // 最后滤镜
                output = filterLast

            } else { // 最后初始
                output = inputFilterGroup
            }
        }

        return output
    }

    // Internal

    /// 输入
    var inputType: InputType?

    var _aspectRatio: AspectRatio = .ar_16_9

    /// 画面裁剪滤镜
    lazy var cropFilter: GPUImageCropFilter = {
        let cropFilter = GPUImageCropFilter()

        cropFilter.frameProcessingCompletionBlock = { [weak self] _, _ in

            guard let weakSelf = self else { return }

            weakSelf.updateElement()
        }

        return cropFilter
    }()

    /// 曝光滤镜
    lazy var exposureFilter: GPUImageExposureFilter = {
        let exposureFilter = GPUImageExposureFilter()

        return exposureFilter
    }()

    /// 默认输入滤镜组
    lazy var inputFilterGroup: GPUImageFilterGroup = {
        let group = GPUImageFilterGroup()

        return group
    }()

    /// 滤镜集合
    var filterList: [BaseFilter] = []
    /// 水印集合
    var watermarkList: [Watermark] = []
    /// 输出集合
    var outputs: [OutputProtocol] = []

    func config() {
        // 设置输入画面预处理的相关滤镜

        cropFilter.addTarget(exposureFilter)

        inputFilterGroup.initialFilters = [cropFilter] // 起始

        inputFilterGroup.terminalFilter = exposureFilter // 末尾

        // 构建初始链

        inputFilterGroup.addTarget(filterChain.header)

        filterChain.header.addTarget(filterChain.footer)

        filterChain.footer.addTarget(watermarkChain.header)

        watermarkChain.header.addTarget(watermarkChain.footer)
    }
    
    
    /// 水印数量
    func watermarkCount() -> Int {
        return watermarkList.count
    }
}
